using System;
using System.Data;
using System.Data.SqlClient;
using System.Xml;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (pty) ltd
	Author:		Alan Benington
	Started:	2007-05-27	
	Status:		redev	
	Version:	2.0.0
	Build:		20070527
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/
	
/*	-------------------------------------------------------------------------------------------------
	Note re EngineX.PassportX:
	------------------------------------
	The refactoring mentioned below is intended to result in a code base that can be migrated
	into the EngineX framework as follows:
	- Base classes migrated to the EngineX.PassportX namespace.
	- Web Service classes migrated to the EngineX.PassportServiceX namespace.
	- Web service classes can remain in an implementation class (eg NashuaMobile.Gatekeeper)
	Note: Once this is completed the Gatekeeper code will become dependant on PassportX base classes.
		  If this is not desired, a fork in the codebase will be created at that stage.
	-------------------------------------------------------------------------------------------------	*/

/*	-----------------------------------------------------------------------
	Development Notes:
	==================

	20070220:	This base class was taken from the previous GateKeeper 
				class and split into two (ie this and GateKeeperBase)
				Class hierarchy as follows:
				   GateKeeperResult_
									|_ System.Xml.XmlDocument
	20070527:	Starting point from NMGatekeeper.2.0.2.
				Class hierarchy now becomes:
					x_result
							|_ System.Xml.XmlDocument
				Note: this class should/could be derived from engineX.x_status
	20070703:	Removed net_2_0 directive (from compatibility build)
	-----------------------------------------------------------------------	*/

namespace umlungu.engineX.passportX {
	/// <summary>
	/// The NMErorr class implments a universal error handler for the GK*  classes
	/// </summary>
	public class x_result : System.Xml.XmlDocument {
		#region Invisible properties
		#if net_1_1
		PassportUri uri;
		#endif
		#endregion

		#region Constants
		private const string RESULT_XML = "<{0}><Result><ResultCode>0</ResultCode><Description/></Result></{0}>";
		#endregion

		#region Visible properties
		private string tag = "GateKeeper";
		/// <summary>The tag for the error object</summary>
		/// <value>A string containing a description of the error</value>
		public string Tag {
			get { return tag; }
			set { tag = value; initialise(); }
		}
		private string message;
		/// <summary>The message associated with the error</summary>
		/// <value>A string containing a description of the error</value>
		public string Message {
			get { return message; }
			set { message = value; MessageElem.InnerText = message; }
		}
		private string code;
		/// <summary>The code associated with the error</summary>
		/// <value>A string containing the error code</value>
		public string Code {
			get { return code; }
			set { code = value; CodeElem.InnerText = value; }
		}
		/// <summary>The message XmlElement associated with the error</summary>
		/// <value>An XmlElement containing a description of the error</value>
		public XmlElement MessageElem {
			get { return DocumentElement.SelectSingleNode("//Result/Description") as XmlElement; }
		}
		/// <summary>The code XmlElement associated with the error</summary>
		/// <value>An XmlElement containing the error code</value>
		public XmlElement CodeElem {
			get { return DocumentElement.SelectSingleNode("//Result/ResultCode") as XmlElement; }
		}
		#endregion

		#region Constructors/Destructors
		/// <overloads>Constructor</overloads>
		/// <summary>Default constructor</summary>
		public x_result() : base() {
			initialise();
		}
		/// <summary>Constructor with root tag</summary>
		public x_result(string tg) : base() {
			initialise(tg);
		}
		#endregion

		#region Public methods
		#endregion
		
		#region Protected methods
		/// <overloads>Load error for a specific error condition</overloads>
		/// <summary>Code and message</summary>
		protected void Error(int cde, string msg) {
			initialise(cde.ToString(), msg);
		}
		/// <summary>Code and two messages</summary>
		protected void Error(int cde, string msg, string add) {
			initialise(cde.ToString(), String.Concat(msg, " - ", add));
		}
		/// <summary>Code and message</summary>
		protected void Error(int cde, string msg, Exception exc) {
			initialise(cde.ToString(), msg, exc);
		}
		/// <summary>Exception, code and message</summary>
		protected void Error(string cde, string msg, Exception exc) {
			initialise(cde, msg, exc);
		}
		
		/// <overloads>Adds a node to the Document</overloads>
		/// <summary>Adds a child of document element</summary>
		protected XmlElement _AddElement(string name) {
			return DocumentElement.AppendChild(CreateElement(name)) as XmlElement;
		}
		/// <summary>Adds a child to an element</summary>
		protected XmlElement _AddElement(XmlNode parent, string name) {
			return parent.AppendChild(CreateElement(name)) as XmlElement;
		}
		/// <summary>Adds child of document element</summary>
		protected void _AddElement(string name, string value) {
			DocumentElement.AppendChild(CreateElement(name)).InnerText = value;
		}
		/// <summary>Adds grandchild of document element</summary>
		protected void _AddElement(string parent, string name, string value) {
			XmlNode child = DocumentElement.SelectSingleNode(parent);
			if (child == null)
				child = DocumentElement.AppendChild(CreateElement(parent));
			child.AppendChild(CreateElement(name)).InnerText = value;
		}
		
		/// <overloads>Adds a attribute to the Document</overloads>
		/// <summary>Adds to document element</summary>
		protected void _AddAttribute(string name, string value) {
			XmlAttribute attr = CreateAttribute(name);
			attr.Value = value;
			DocumentElement.SetAttributeNode(attr);
			//DocumentElement.SetAttribute(name,value);
		}
		/// <summary>Adds to document element</summary>
		protected void _AddAttribute(string name, int value) {
			XmlAttribute attr = CreateAttribute(name);
			attr.Value = value.ToString();
			DocumentElement.SetAttributeNode(attr);
			//DocumentElement.SetAttribute(name, value.ToString());
		}
		/// <summary>Adds to child of document element</summary>
		protected void _AddAttribute(string parent, string name, string value) {
			XmlElement child = DocumentElement.SelectSingleNode(parent) as XmlElement;
			if (child == null)
				child = DocumentElement.AppendChild(CreateElement(parent)) as XmlElement;
			child.SetAttribute(name, value);
		}
		#endregion
		
		#region Private methods
		/// <overloads>Initialises the object (called from constructors)</overloads>
		/// <summary></summary>
		private void initialise() {
			LoadXml(string.Format(RESULT_XML, tag));
			#if net_1_1
			uri = new PassportUri("http://www.umlungu.com/");
			#endif
		}
		private void initialise(string tg) {
			tag = tg;
			initialise();
		}
		private void initialise(string cde, string msg) {
			initialise();
			Code = cde;
			Message = msg;
		}
		private void initialise(string tg, string cde, string msg) {
			tag = tg;
			initialise(cde, msg);
		}
		private void initialise(string cde, string msg, Exception exc) {
			initialise(cde, String.Concat(msg, " - ", exc.Source, " - ", exc.Message));
			DocumentElement.AppendChild(CreateElement("StackTrace")).InnerText = exc.StackTrace;
		}
		#endregion
	}
}
